After kicking around many too-complicated solutions, apply the buffer
authorrobertl <robertl>
Sat, 7 Oct 2006 17:38:56 +0000 (17:38 +0000)
committerrobertl <robertl>
Sat, 7 Oct 2006 17:38:56 +0000 (17:38 +0000)
reallocation fix for gbfile.  Tested on Windows and Linux with forced
buffer reallocs.

gbfile.c

index f4773a3c4e7879a2264b632e0ee1325c6757ba6f..ef60719a6a6e644ff199371c0dce25fd70ec5ee2 100644 (file)
--- a/gbfile.c
+++ b/gbfile.c
@@ -261,17 +261,26 @@ gbfprintf(gbfile *file, const char *format, ...)
                len = vsnprintf(file->buff, file->buffsz, format, args);
                va_end(args);
 
-               if (len < 0)
-                       fatal(MYNAME ": Unexpected vsnprintf error %d (%s/%s)!\n", 
-                               len, file->module, file->name);
-               else if (len == 0)
-                       return 0;
-               else if (len < file->buffsz) 
+               /* Unambiguous Success */
+               if ((len > -1) && (len < file->buffsz))
                        break;
 
-               while (file->buffsz <= len) 
+               /* First case: C99 behaviour.  Len is correctly sized.
+                * add space for null terminator.  Next time through the
+                * loop we're guaranteed success.
+                * 
+                * Second case: SUS (and Windows) behaviour.  We know it
+                * doesn't fit, but we don't know how big it has to be.
+`               * double it and try again.  We'll loop until we succeed.
+                *
+                * Since we keep the I/O buffer in the file handle, we
+                * quickly reach a steady state on the size of these buffers.
+                */
+               if (len > -1) 
+                       file->buffsz = len + 1;
+               else 
                        file->buffsz *= 2;
-                       
+
                file->buff = xrealloc(file->buff, file->buffsz);
        }
        return gbfwrite(file->buff, 1, len, file);